package com.aaa.security.aspect;

import com.aaa.common.util.JWTUtil;
import com.aaa.security.annotation.RequiresPermissions;
import com.aaa.security.exception.PermissionException;
import com.aaa.security.utils.WebUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

@Component//该类交于spring容器创建和管理
@Aspect //表示该类为切面类
public class PreAuthorizeAspect {
    //切点：在哪些位置上添加我们的aop切面
    @Pointcut(value = "@annotation(com.aaa.security.annotation.RequiresPermissions)")
    public void pointcut(){}

    @Around(value = "pointcut()")
    public Object around(ProceedingJoinPoint joinPoint){
        //获取连接点的方法--获取哪些方法使用了RequiresPermissions
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        //获取方法上的RequiresPermissions
        checkAnnotation(methodSignature.getMethod());
        //回调接口方法
        Object result = null;
        try {
            result = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        return result;
    }
    private void checkAnnotation(Method method){
        RequiresPermissions requiresPermissions = method.getAnnotation(RequiresPermissions.class);
        if(requiresPermissions!=null){
            //判断当前用户是否具有注解上的权限
            String value = requiresPermissions.value();
            //token中包含权限信息。
            HttpServletRequest request = WebUtils.getRequest();
            String token = request.getHeader("token");

            Map<String, Object> map = JWTUtil.getTokenChaim(token);
            List<String> permissions = (List<String>) map.get("permissions");
            if(!permissions.contains(value)){
                throw new PermissionException("权限不足");
            }
        }
    }
}
